#!/usr/bin/perl -wT
use CGI qw(:standard);
use CGI::Carp qw(fatalsToBrowser);
use Date::Simple ('date', 'today');
use POSIX ('strftime');
use HTML::Template;
use File::Basename;

BEGIN { push @INC, "/home/erik/public_html/Isabel"; }

use main;

use strict;

# -----------------
# Configuration

my $homeDirectory = "/home/erik/public_html/Isabel"; # dirname($ENV{'SCRIPT_FILENAME'});
my $templateItem = "$homeDirectory/template/template_image.tmpl";
my $templateGallery = "$homeDirectory/template/template_gallery.tmpl";
my $templateViewer = "$homeDirectory/template/template_viewer.tmpl";

# -----------------
# CGI params
#
# URL Format: main.pl?Item=<filename>&Tag=<tag>&Page=<page>
#
# Item: filename of the item, minus extension
# Tag:  tag for the gallery to view item in   
# Page: page within the gallery for this tag
#
# "New" is a reserved tag for the "what's new" gallery
#
# If Item specified, view that item. If Tag matches item's tags, view
# in that gallery. Otherwize, tag is ignored (view in all items). Page
# is ignored.
#
# Else, if tag specified, view that tag's gallery. If page specified,
# view that page in the gallery. Otherwize, Page is ignored.
#
# Else, we have an error

my $item = param("Item");
my $tag  = param("Tag");
my $page = param("Page");

my $newstartdate = cookie("NewStartDate");
my $newenddate   = cookie("NewEndDate");

# Defaults if the cookies are missing

if( !$newstartdate ) { $newstartdate = date('2005-12-20'); }
if( !$newenddate   ) { $newenddate = today(); }

# -----------------
# Load all items
# 
# We fill the global array @items with everything we find in the item
# directories. Currently, these are directories starting with "Photos"

my @items = ();

if( opendir(ROOTDIR, "$homeDirectory") )
{
    my $itemdir;

    foreach $itemdir (grep(/Photos.*/, readdir(ROOTDIR)))
    {
        if( opendir(ITEMDIR, "$homeDirectory/$itemdir") )
        {
            foreach (readdir(ITEMDIR))
            {
                if( /([0-9]{8}-[0-9]{6})\.(jpg|avi|mp4|wmv|mp3)/ )
                {
                    my $homedir  = $homeDirectory; # $_[0];
                    my $itemdir  = $itemdir; #$_[1];
                    my $item     = $1; #$_[2];
                    my $itemtype = $2; #$_[3];

                    my $filebase = "$homedir/$itemdir/$item";
                    
                    my $file        = $filebase . ".$itemtype";
                    my $captionfile = $filebase . ".txt";
                    my $tagfile     = $filebase . ".tags.txt";

                    my $caption;
                    my $description;

                    if( -e $captionfile )
                    {
                        open(CAPTIONFILE, $captionfile);
                        $caption = <CAPTIONFILE>;
                        $description = "";
                        while(<CAPTIONFILE>) {$description = $description . $_;}
                        close(CAPTIONFILE);
                        
                        $caption =~ s/\s*$//g;
                        $caption =~ s/&/&amp;/g;
                        
                        if( $description ne "" )
                        {
                            $description =~ s/\s*$//g;
                            $description =~ s/&/&amp;/g;
                        }
                    }
                    else
                    {
                        $caption = $description = $item;
                    }

                    my $tags = "";

                    if( -e $tagfile )
                    {
                        open(TAGFILE, $tagfile);
                        $tags = <TAGFILE>;
                        close(TAGFILE);
                    }

                    my @stats = stat($file);

                    push @items, {
                        'item' => $item,
                        'dir'  => $itemdir,
                        'type' => $itemtype,
                        'date' => strftime("%Y-%m-%d", localtime($stats[9])),
                        'caption'     => $caption,
                        'description' => $description,
                        'tags' => $tags
                    };
                }
            }
            
            closedir(ITEMDIR);
        }
    }
    
    closedir(ROOTDIR);
}

# ----------------- 
# Sort all items by item name (implicit sort by date/time)

@items = sort { $a->{'item'} cmp $b->{'item'} } @items;

# ----------------- 
# Filter items based on tag

my $tag_title;
my $tag_param;

if( $tag )
{
    my @tag_items = ();

    if( $tag eq "New" )
    {
        # If the end date for the current range is not today, then
        # this is a new visit. Update the dates.
    
        if( $newenddate ne today() )
        {
            $newstartdate = $newenddate;
            $newenddate = today();
        }

        $tag_title = "What's New (since $newstartdate)";
        $tag_param = "Tag=$tag";

        # Match if item's modification date is later than the start date
        
        @tag_items = map { $_->{'date'} ge $newstartdate ? $_ : () } @items;
    }
    elsif( $tag =~ /([0-9]{4})([0-9]{2})/ )
    {
        $tag_title = main::month_name($2) . " " . $1;
        $tag_param = "Tag=$tag";
        
        # Match if the item's actual date matches the month/year specified
        # in $tag
        
        @tag_items = map { ($_->{'item'} =~ /^$tag/) ? $_ : () } @items;
    }
    else
    {
        $tag_title = "$tag";
        $tag_param = "Tag=$tag";

        # Match if the specified tag is in an item's tag list

        @tag_items = map { ($_->{'tags'} =~ /$tag/) ? $_ : () } @items;
    }

    if( $item )
    {
        # If we're looking at an item, see if it's in the tag
        # items. Set @items to the tag set if it's in there, otherwize
        # clear the tag and use all items.

        my $found_it = 0;

        foreach ( @tag_items )
        {
            if( $_->{'item'} eq $item )
            {
                @items = @tag_items;
                
                $found_it = 1;
                
                last;
            }
        }
        
        if( $found_it != 1 )
        {
            $tag_title = "Everything";
            $tag_param = "";
        }
    }
    else
    {
        # No item specified, tag takes precedence
        
        @items = @tag_items;
    }
}
else
{
    $tag_title = "Everything";
    $tag_param = "";

    # No tag specifed, leave tag item list empty
}

# -----------------
# Header
#
# Update the date cookies if and only if we're looking at "what's
# new". Don't update the dates otherwize, or client might miss
# something new. Say they view an item one day, and then go to "what's
# new" another day...

if( $tag && ($tag eq "New") )
{
    # print the header 
    
    my $cookiestart = &cookie(-name=>"NewStartDate",
                              -value=>"$newstartdate",
                              -expires=>"+1y",
                              -path=>"/");
    
    my $cookieend   = &cookie(-name=>"NewEndDate",
                              -value=>"$newenddate",
                              -expires=>"+1y",
                              -path=>"/");
    
    print header(-cookie=>[$cookiestart,$cookieend]);
}
else
{
    print header;
}

# ----------------- 
# Select a template and fill it out
#

my $template;

if( $item )
{
    # Item specified, load the item template

    $template = HTML::Template->new( filename => $templateItem, 
                                     cache => '1',
                                     die_on_bad_params => '0' );
    

    # Find item in the tag items
    
    my $item_number;

    foreach ( @items )
    {
        $item_number += 1;

        if( $_->{'item'} eq $item )
        {
            last;
        }
    }

    # Use item number to find page in current tag gallery

    my $gallerypage = int(($item_number - 1) / 12) + 1;

    # Last item number 
    
    my $lastitem = scalar( @items );
    
    # Set the title

    $template->param( 
        Title => $tag_title . ": Item $item_number of $lastitem" );

    # Navigation

    #--- First 
    if( $item_number > 1 )
    {
        $template->param(
            FirstItemHref => "main.pl?Item=$items[0]{'item'}&amp;$tag_param");
    }

    #--- Previous
    if( $item_number > 1 )
    {
        my $pi = $item_number - 2;

        $template->param( 
            PrevItemHref => "main.pl?Item=$items[$pi]{'item'}&amp;$tag_param");
    }

    #--- Up to Gallery Page
    $template->param( UpHref => "main.pl?$tag_param&amp;Page=$gallerypage" );

    #--- Next
    if( $item_number < $lastitem )
    {
        my $ni = $item_number;

        $template->param(
            NextItemHref => "main.pl?Item=$items[$ni]{'item'}&amp;$tag_param");
    }

    #--- Last
    if( $item_number < $lastitem )
    {
        $template->param(
            LastItemHref => "main.pl?Item=$items[$lastitem - 1]{'item'}&amp;$tag_param");
    }

    # fill in the rest of the template

    $template->param( 
        main::item_template_values($items[$item_number - 1], $tag));
}
else
{
    # No item, looking at a gallery

    $template = HTML::Template->new( filename => $templateGallery,
                                     cache => '1', 
                                     die_on_bad_params => '0' );

    # Validate page number 

    my $lastpage;

    if( @items > 0 )
    {
        $lastpage = int( (scalar @items - 1) / 12 + 1);
    }
    else
    {
        $lastpage = 1;
    }
   
    if( !$page || $page < 1 || $page > $lastpage )
    {
        $page = 1;
    }

    # set title

    $template->param( Title => $tag_title . ": Page $page of $lastpage" );

    #--- First 
    if( $page > 1 )
    {
        $template->param( FirstPageHref => "main.pl?$tag_param&amp;Page=1" );
    }

    #--- Previous
    if( $page > 1 )
    {
        my $prevpage = $page - 1;
        $template->param( PrevPageHref => "main.pl?$tag_param&amp;Page=$prevpage" );
    }
    
    #--- Up to Main Page
    $template->param( UpHref => "index.html?Tab=Galleries" );

    #--- Next
    if( $page < $lastpage )
    {
        my $nextpage = $page + 1;
        $template->param( NextPageHref => "main.pl?$tag_param&amp;Page=$nextpage" );
    }

    #--- Last
    if( $page < $lastpage )
    {
        $template->param( LastPageHref => "main.pl?$tag_param&amp;Page=$lastpage" );
    }

    # Items. (calculate first item index from page)

    my $galleryempty = 1;

    my $index = ($page * 12) - 12;

    my @table_data = ();

    foreach (1 .. 3)
    {
        if( $index >= scalar @items )
        {
            last;
        }

        $galleryempty = 0;

        my @col_data = ();

        foreach (1 .. 4)
        {
            if( $index  >= scalar @items )
            {
                last;
            }

            my %item_data = 
                main::item_template_values($items[$index], $tag);

            push(@col_data, \%item_data);
            
            $index += 1;
        }

        my %row_data;
        
        $row_data{GalleryColLoop} = \@col_data;

        push(@table_data, \%row_data);
    }

    $template->param( GalleryRowLoop => \@table_data );

    if( $galleryempty )
    {
        $template->param( GalleryEmpty => "Yes" );
    }
}

# -----------------
# Finally, print the page
    
print $template->output;

